package github.flandre.examplemod.common.energy.tileentity;

import com.mojang.datafixers.DSL;
import github.flandre.examplemod.common.energy.block.FEDemoMachineBlock;
import github.flandre.examplemod.network.NetworkRegistryHandler;
import github.flandre.examplemod.network.Packet.PowerClinetForServer;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.multiplayer.PlayerController;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.potion.EffectInstance;
import net.minecraft.potion.Effects;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.registries.ObjectHolder;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Objects;

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public class FEDemoMachineTileEntity extends TileEntity implements ITickableTileEntity
{
    public static final String NAME = "examplemod:machine";

    private int energy = 0;

    @ObjectHolder(NAME)
    public static TileEntityType<FEDemoMachineTileEntity> TILE_ENTITY_TYPE;

    @SubscribeEvent
    public static void onRegisterTileEntityType(@Nonnull RegistryEvent.Register<TileEntityType<?>> event)
    {
        event.getRegistry().register(TileEntityType.Builder.create(FEDemoMachineTileEntity::new,
                FEDemoMachineBlock.BLOCK).build(DSL.remainderType()).setRegistryName(NAME));//（代表未知类型)
    }

    private FEDemoMachineTileEntity()
    {

        super(TILE_ENTITY_TYPE);
    }

    //机器的序列化


    @Override
    public void read(@NotNull BlockState state, CompoundNBT compound) {
        this.energy = compound.getInt("MachineEnergy");
        super.read(state, compound);
    }


    @Nonnull
    @Override
    public CompoundNBT write(@Nonnull CompoundNBT compound)
    {
        compound.putInt("MachineEnergy", this.energy);
        return super.write(compound);
    }

    private final LazyOptional<IEnergyStorage> lazyOptional  = LazyOptional.of(() -> new IEnergyStorage()
    {
        @Override //接收能量
        public int receiveEnergy(int maxReceive, boolean simulate)
        {
            int energy = this.getEnergyStored(); //当前能量
            int diff = Math.min(this.getMaxEnergyStored() - energy, maxReceive); //能接收多少能量
            if (!simulate)
            {
                FEDemoMachineTileEntity.this.energy += diff;
                if (diff != 0)
                {
                    FEDemoMachineTileEntity.this.markDirty(); //保存
                }
            }
            return diff;
        }

        @Override
        public int extractEnergy(int maxExtract, boolean simulate)
        {
            return 0;
        }

        @Override
        public int getEnergyStored()
        {
            return Math.max(0, Math.min(this.getMaxEnergyStored(), FEDemoMachineTileEntity.this.energy));
        }

        @Override
        public int getMaxEnergyStored()
        {
            return 192_000;
        }

        @Override
        public boolean canExtract()
        {
            return false;
        }

        @Override
        public boolean canReceive()
        {
            return true;
        }
    });

    //构建能力
    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, Direction side)
    {
        //禁止上下两个面
        boolean isEnergy = Objects.equals(cap, CapabilityEnergy.ENERGY) && side.getAxis().isHorizontal();
        return isEnergy ? this.lazyOptional.cast() : super.getCapability(cap, side);
    }




    int count = 0;
    @Override
    public void tick() {
        if (this.world != null && !this.world.isRemote)
        {
            count++;
            if(count == 100)
            {
                count = 0;
                TileEntity tileEntity = getTileEntity();
                if(tileEntity instanceof FEDemoMachineTileEntity)
                {
                    //获取这个区域的玩家列表
                    AxisAlignedBB axisalignedbb = (new AxisAlignedBB(this.pos)).grow(10).expand(0, (double)this.world.getHeight(), 0);
                    List<PlayerEntity> list = this.world.getEntitiesWithinAABB(PlayerEntity.class, axisalignedbb);

                    for(PlayerEntity playerentity : list) {
                        int diff = Math.min(this.energy, 1000);
                        if (diff > 0)
                        {
                            playerentity.heal(4);
                            playerentity.addPotionEffect(new EffectInstance(Effects.LUCK,100,5, true, true));
                            this.energy -= diff;
                            this.markDirty();
                        }
                    }

                }
            }
        }
    }

    //给实体回血
    public void heal(@Nonnull LivingEntity entity)
    {
        int diff = Math.min(this.energy, 100);
        if (diff > 0)
        {

            entity.heal((float) diff / 1_000);
            this.energy -= diff;
            this.markDirty();
        }
    }
}
